/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.annotation.AnGenerics;

/**
 * 注解工具类
 *
 * @version v1.0.0 @author zouzhigang 2016-12-23 新建与整理
 */
@AnAlias("Annotations")
public class Annotations
{
    /***************************************************************************************/
    //以下为类相关注解
    /***************************************************************************************/
    
    /**
     * 获取类可能的别名
     * 
     * @param cls   类结构
     * @return      类别名，如果没有或为空白还回null
     */
    public static String getClassAlias(Class<?> cls)
    {
        AnAlias alias = cls.getAnnotation(AnAlias.class);
        if (alias != null && !Validates.isEmptyBlank(alias.value()[0]))
            return alias.value()[0].trim();
        
        return null;
    }
    
    /***************************************************************************************/
    //以下为字段相关注解
    /***************************************************************************************/
    
    /**
     * 获取字段的名称，如果有指定Alias且不为空，取Alias中的值，否则取field.getName()
     * 
     * @param field 字段
     * @return      该字段的名称或配置Alias的值
     */
    public static String getFieldName(Field field)
    {
        AnAlias alias = field.getAnnotation(AnAlias.class);
        if (alias != null && Validates.isNotEmptyBlank(alias.value()[0]))
            return alias.value()[0].trim();
        else
            return field.getName();
    }
    
    /**
     * 获取字段的泛型，当为Collection的子类时有效，如果传入的是数组，直接返回数组组件类型
     * 
     * @param field 字段
     * @return      该字段的名称或配置Generic的值
     */
    public static Class<?> getGenericsClass(Field field)
    {
        if (Types.isArray(field.getType()))
            return field.getType().getComponentType();
        
        AnGenerics generics = field.getAnnotation(AnGenerics.class);
        return generics == null?null:generics.value();
    }
    
    /********************************************************/
    //以下为方法相关注解
    /********************************************************/
    
    /**
     * 获取方法的名称，如果有指定Alias且不为空，取Alias中的值，否则取method.getName()
     * 
     * @param method 方法
     * @return       该方法的名称或配置Alias的值
     */
    public static String getMethodName(Method method)
    {
        AnAlias alias = method.getAnnotation(AnAlias.class);
        if (alias != null && Validates.isNotEmptyBlank(alias.value()[0]))
            return alias.value()[0].trim();
        else
            return method.getName();
    }
    
    /**
     * 获取方法的别名，如果没有或为空白，返回null
     * 
     * @param method 方法
     * @return       该方法配置Alias的值
     */
    public static String getMethodAlias(Method method)
    {
        AnAlias alias = method.getAnnotation(AnAlias.class);
        if (alias == null || Validates.isEmptyBlank(alias.value()[0]))
            return null;
        
        return alias.value()[0].trim();
    }
    
    /**
     * 判断指定的名称是不是访方法的名称或别名
     * 
     * @param method 方法
     * @param name   名称
     * @return       =true表示匹配成功
     */
    public boolean isMethodNameOrAlias(Method method, String name)
    {
        if (Validates.isEmptyBlank(name))
            return false;
        
        if (name.equals(method.getName()))
            return true;
        
        AnAlias alias = method.getAnnotation(AnAlias.class);
        return (alias != null && name.equals(alias.value()[0].trim()));
    }
}
